home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Meeting Pearls 4
/
Meeting Pearls Vol. IV (1996)(GTI - Schatztruhe)[!].iso
/
Pearls
/
dev
/
Oberon
/
OberonV4
/
system
/
Decoder.Mod
(
.txt
)
< prev
next >
Wrap
Oberon Text
|
1994-08-02
|
66KB
|
2,112 lines
Syntax10.Scn.Fnt
MODULE Decoder;
(* Disassembler for MC68020-code with coprocessor MC68881.
Diplomarbeit Samuel Urech
Programming language: Oberon-2 on Ceres-1
Date: 7.11.92 Current version: 23.2.93 *)
IMPORT Oberon, Texts, Files, TextFrames, MenuViewers;
CONST DUMMY = 0;
PC = -1;
(* instructions *)
ORI = 0; ANDI = 1; EORI = 2; CMPI = 3; ADDI = 4; SUBI = 5; JMP = 6; JSR = 7; PEA = 8; NBCD = 9; TAS = 10;
RTD = 11; STOP = 12; MUL = 13; dIV = 14; ADD = 15; AND = 16; CMP = 17; EOR = 18; oR = 19; SUB = 20;
ABCD = 21; SBCD = 22; PACK = 23; UNPK = 24; ADDA = 25; CMPA = 26; SUBA = 27; ADDX = 28; SUBX = 29;
ASL = 30; ASR = 31; LSL = 32; LSR = 33; ROL = 34; ROR = 35; ROXL = 36; ROXR = 37; BFTST = 38; BFCHG = 39;
BFEXTU = 40; BFEXTS = 41; BFCLR = 42; BFFFO = 43; BFSET = 44;
(* coprocessor opcodes *)
FABS = 18H; FACOS = 1CH; FADD = 22H; FASIN = 0CH; FATAN = 0AH; FATANH = 0DH; FCMP = 38H;
FCOS = 1DH; FCOSH = 19H; FDIV = 20H; FETOX = 10H; FETOXM1 = 8; FGETEXP = 1EH; FGETMAN = 1FH;
FINT = 1; FINTRZ = 3; FLOG10 = 15H; FLOG2 = 16H; FLOGN = 14H; FLOGNP1 = 6; FMOD = 21H; FMOVE = 0;
FMUL = 23H; FNEG = 1AH; FREM = 25H; FSCALE = 26H; FSGLDIV = 24H; FSGLMUL = 27H; FSIN = 0EH;
FSINH = 2; FSQRT = 4; FSUB = 28H; FTAN = 0FH; FTANH = 9; FTENTOX = 12H; FTST = 3AH; FTWOTOX = 11H;
(* Floating Point Condition Codes *)
FEQ = 1; FNE = 0EH; FGT = 12H; FNGT = 1DH; FGE = 13H; FNGE = 1CH; FLT = 14H; FNLT = 1BH; FLE = 15H;
FNLE = 1AH; FGL = 16H; FNGL = 19H; FGLE = 17H; FNGLE = 18H; FOGT = 2; FULE = 0DH; FOGE = 3; FULT = 0CH;
FOLT = 4; FUGE = 0BH; FOLE = 5; FUGT = 0AH; FOGL = 6; FUEQ = 9; fOR = 7; FUN = 8; FF = 0; FT = 0FH;
FSF = 10H; FST = 1FH; FSEQ = 11H; FSNE = 1EH;
(* instruction sizes *)
byte = 0; word = 1; long = 2; other = 3;
(* structure forms *)
Byte = 1; Bool = 2; Char = 3; SInt = 4; Int = 5; LInt = 6; Real = 7; LReal = 8; Set = 9; String = 10;
Pointer = 13; ProcTyp = 14; Comp = 15;
BlockMisaligned = "Block misaligned.";
VAR scanner : Texts.Scanner;
writer : Texts.Writer;
file : Files.File;
rider : Files.Rider;
frame : TextFrames.Frame;
output : Texts.Text;
viewer : MenuViewers.Viewer;
pc : LONGINT;
PROCEDURE Getbits( x : INTEGER; from, to : INTEGER) : INTEGER;
(* Returns a number of bits of a number. *)
BEGIN (* Getbits *)
RETURN SHORT( ASH( x, -to ) MOD ASH( 2, from - to ) )
END Getbits;
PROCEDURE Write( ch : CHAR );
(* Writes a character to the output. *)
BEGIN
Texts.Write( writer,ch );
END Write;
PROCEDURE WriteString( s : ARRAY OF CHAR );
(* Writes a string to the output. *)
BEGIN
Texts.WriteString( writer, s );
END WriteString;
PROCEDURE WriteLn;
(* Writes a line feed to the output. *)
BEGIN
Texts.WriteLn( writer );
END WriteLn;
PROCEDURE WriteInt( x : LONGINT );
(* Writes a longint to the output. *)
BEGIN
Texts.WriteInt( writer, x, 0 );
END WriteInt;
PROCEDURE WriteHex( x : LONGINT );
(* Writes a longint in hexadecimal form to the output. *)
BEGIN
Texts.WriteHex( writer, x );
END WriteHex;
PROCEDURE Read( VAR ch : CHAR );
(* Reads a character from the file. *)
BEGIN (* Read *)
Files.Read( rider, ch );
END Read;
PROCEDURE ReadInt( VAR x : INTEGER );
(* Reads a word from the file. *)
VAR hi, lo : CHAR;
BEGIN (* ReadInt *)
Files.Read( rider, hi );
Files.Read( rider, lo );
x := 100H * ORD( hi )+ ORD( lo );
INC( pc, 2 );
END ReadInt;
PROCEDURE ReadLongint( VAR x : LONGINT );
(* Reads a longword from the file. *)
VAR lo : LONGINT;
hi, l : INTEGER;
BEGIN (* ReadLongint *)
ReadInt( hi );
ReadInt( l ); lo := l;
IF lo < 0 THEN INC( lo, 65536 ); END;
x := 10000H * hi + lo;
END ReadLongint;
PROCEDURE ReadDynint( VAR x : LONGINT );
(* Reads an integer of dynamic length. *)
VAR n : LONGINT;
shift : SHORTINT;
ch : CHAR;
BEGIN (* ReadDynint *)
shift := 0;
n := 0;
Files.Read( rider, ch );
WHILE ORD( ch ) >= 128 DO
INC( n, ASH( ORD( ch ) MOD 128, shift ) );
INC( shift, 7 );
Files.Read( rider, ch );
END; (* WHILE *)
x := n + ASH( ORD( ch ) MOD 64, shift ) - ASH( ORD( ch ) DIV 64, shift ) * 64
END ReadDynint;
PROCEDURE ReadString( VAR string : ARRAY OF CHAR; len : INTEGER );
(* Reads a string from the file. Reads at least len characters. *)
VAR i : INTEGER;
ch : CHAR;
BEGIN (* ReadString *)
i := 0;
REPEAT
Read( ch );
string[ i ] := ch;
INC( i );
UNTIL ch = 0X;
WHILE i < len DO string[ i ] := 0X; Read( ch ); INC( i ); END;
END ReadString;
PROCEDURE WriteType( ch : CHAR );
(* Writes the given type in plain text. *)
BEGIN (* WriteType *)
CASE ORD( ch ) OF
Byte : WriteString( " : BYTE" );
| Bool : WriteString( " : BOOLEAN" );
| Char : WriteString( " : CHAR" );
| SInt : WriteString( " : SHORTINT" );
| Int : WriteString( " : INTEGER" );
| LInt : WriteString( " : LONGINT" );
| Real : WriteString( " : REAL" );
| LReal : WriteString( " : LONGREAL" );
| Set : WriteString( " : SET" );
| String : WriteString( " : String" );
| Pointer : WriteString( " : POINTER" );
| ProcTyp : WriteString( " : PROCEDURE" );
| Comp : WriteString( " : Composite" );
ELSE WriteString( " : Undefined" );
END; (* CASE *)
WriteString( " " );
END WriteType;
PROCEDURE WriteRegister( da, reg : INTEGER );
(* Writes a register. *)
BEGIN (* WriteRegister *)
IF da = 0 THEN
Write( "D" );
ELSE
Write( "A" );
END; (* IF *)
WriteInt( reg );
END WriteRegister;
PROCEDURE WriteCondition( condition : INTEGER );
(* Writes a condition. *)
BEGIN (* WriteCondition *)
CASE condition OF
0 : Write( "T" );
| 1 : Write( "F" );
| 2 : WriteString( "HI" );
| 3 : WriteString( "LS" );
| 4 : WriteString( "CC" );
| 5 : WriteString( "CS" );
| 6 : WriteString( "NE" );
| 7 : WriteString( "EQ" );
| 8 : WriteString( "VC" );
| 9 : WriteString( "VS" );
| 10 : WriteString( "PL" );
| 11 : WriteString( "MI" );
| 12 : WriteString( "GE" );
| 13 : WriteString( "LT" );
| 14 : WriteString( "GT" );
| 15 : WriteString( "LE" );
END; (* CASE *)
END WriteCondition;
PROCEDURE WriteFloatCondition( condition : INTEGER );
(* Writes a coprocessor condition. *)
BEGIN (* WriteFloatCondition *)
CASE condition OF
FEQ : WriteString( "EQ" );
| FNE : WriteString( "NE" );
| FGT : WriteString( "GT" );
| FNGT : WriteString( "NGT" );
| FGE : WriteString( "GE" );
| FNGE : WriteString( "NGE" );
| FLT : WriteString( "LT" );
| FNLT : WriteString( "NLT" );
| FLE : WriteString( "LE" );
| FNLE : WriteString( "NLE" );
| FGL : WriteString( "GL" );
| FNGL : WriteString( "NGL" );
| FGLE : WriteString( "GLE" );
| FNGLE : WriteString( "NGLE" );
| FOGT : WriteString( "OGT" );
| FULE : WriteString( "ULE" );
| FOGE : WriteString( "OGE" );
| FULT : WriteString( "ULT" );
| FOLT : WriteString( "OLT" );
| FUGE : WriteString( "UGE" );
| FOLE : WriteString( "OLE" );
| FUGT : WriteString( "UGT" );
| FOGL : WriteString( "OGL" );
| FUEQ : WriteString( "UEQ" );
| fOR : WriteString( "OR" );
| FUN : WriteString( "UN" );
| FF : Write( "F" );
| FT : Write( "T" );
| FSF : WriteString( "SF" );
| FST : WriteString( "ST" );
| FSEQ : WriteString( "SEQ" );
| FSNE : WriteString( "SNE" );
END; (* CASE *)
END WriteFloatCondition;
PROCEDURE WriteSize( size : INTEGER );
(* Writes an operand size. *)
BEGIN
CASE size OF
byte : WriteString( ".B " );
| word : WriteString( ".W " );
| long : WriteString( ".L " );
| other : WriteString( "illegal operand size." );
END; (* CASE *)
END WriteSize;
PROCEDURE WriteFloatFormat( format : INTEGER; VAR size : INTEGER );
(* Writes an operand format of the coprocessor and returns the size of integer formats. *)
BEGIN (* WriteFloatFormat *)
size := other;
CASE format OF
0 : WriteString( "L " ); size := long;
| 1 : WriteString( "S " );
| 2 : WriteString( "X " );
| 3 : WriteString( "P " );
| 4 : WriteString( "W " ); size := word;
| 5 : WriteString( "D " );
| 6 : WriteString( "B " ); size := byte;
| 7 : WriteString( "P " );
END; (* CASE *)
END WriteFloatFormat;
PROCEDURE WriteComplexAddrMode( reg : INTEGER );
(* Reads extension word(s) if necessary and writes a complex adressing mode.
If reg = PC, the addressing mode is PC-relative. *)
VAR extension, bdSize, suppressBase, disp : INTEGER;
PROCEDURE WriteBaseDisplacement( bdSize, suppressBase, reg : INTEGER );
(* Reads the base displacement and writes it, writes address register or "CB", if necessary. *)
VAR displacement : INTEGER;
longDisplacement, offset : LONGINT;
BEGIN (* WriteBaseDisplacement *)
IF reg = PC THEN
offset := pc - 2;
ELSE
offset := 0;
END; (* IF *)
CASE bdSize OF
0 : WriteString( "illegal displacement size." );
| 1 : (* no displacement *)
| 2 : ReadInt( displacement );
WriteInt( displacement + offset );
| 3 : ReadLongint( longDisplacement );
WriteInt( longDisplacement + offset );
END; (* CASE *)
IF suppressBase = 0 THEN
IF reg = PC THEN
WriteString( ", PC" );
ELSE
WriteString( ", A" );
WriteInt( reg );
END; (* IF *)
END; (* IF *)
END WriteBaseDisplacement;
PROCEDURE WriteIndexRegister( extension : INTEGER );
(* Writes an index register with size and scaling. *)
BEGIN (* WriteIndexRegister *)
WriteRegister( Getbits( extension, 15, 15 ), Getbits( extension, 14, 12 ) );
IF Getbits( extension, 11, 11 ) = 0 THEN
WriteString( ".W*" );
ELSE
WriteString( ".L*" );
END; (* IF *)
CASE Getbits( extension, 10, 9 ) OF
0 : Write( "1" );
| 1 : Write( "2" );
| 2 : Write( "4" );
| 3 : Write( "8" );
END; (* CASE *)
END WriteIndexRegister;
PROCEDURE WriteOuterDisplacement( long : BOOLEAN );
(* Writes the outer displacement, which can be one or two words. *)
VAR displacement : INTEGER;
longDisplacement : LONGINT;
BEGIN (* WriteOuterDisplacement *)
IF long THEN
ReadLongint( longDisplacement );
WriteInt( longDisplacement );
ELSE
ReadInt( displacement );
WriteInt( displacement );
END; (* IF *)
END WriteOuterDisplacement;
BEGIN (* WriteComplexAddrMode *)
ReadInt( extension );
Write( "(" );
IF Getbits( extension, 8, 8 ) = 0 THEN
disp := Getbits( extension, 7, 0 );
IF reg = PC THEN
IF disp > 127 THEN
WriteInt( pc - 2 + disp - 256 );
ELSE
WriteInt( pc - 2 + disp );
END; (* IF *)
WriteString( ", CB" );
ELSE
IF disp > 127 THEN
WriteInt( disp - 256 );
ELSE
WriteInt( disp );
END; (* IF *)
WriteString( ", A" );
WriteInt( reg );
END; (* IF *)
WriteString( ", " );
WriteIndexRegister( extension );
ELSE
bdSize := Getbits( extension, 5, 4 );
suppressBase := Getbits( extension, 7, 7 );
IF Getbits( extension, 6, 6 ) = 0 THEN
CASE Getbits( extension, 2, 0 ) OF
0 : WriteBaseDisplacement( bdSize, suppressBase, reg );
WriteString( ", " );
WriteIndexRegister( extension );
| 1 : Write( "[" );
WriteBaseDisplacement( bdSize, suppressBase, reg );
WriteString( ", " );
WriteIndexRegister( extension );
Write( "]" );
| 2 : Write( "[" );
WriteBaseDisplacement( bdSize, suppressBase, reg );
WriteString( ", " );
WriteIndexRegister( extension );
WriteString( "], " );
WriteOuterDisplacement( FALSE );
| 3 : Write( "[" );
WriteBaseDisplacement( bdSize, suppressBase, reg );
WriteString( ", " );
WriteIndexRegister( extension );
WriteString( "], " );
WriteOuterDisplacement( TRUE );
| 4 : WriteString( "illegal addressing mode." );
| 5 : Write( "[" );
WriteBaseDisplacement( bdSize, suppressBase, reg );
Write( "]" );
WriteString( ", " );
WriteIndexRegister( extension );
| 6 : Write( "[" );
WriteBaseDisplacement( bdSize, suppressBase, reg );
WriteString( "], " );
WriteIndexRegister( extension );
WriteString( ", " );
WriteOuterDisplacement( FALSE );
| 7 : Write( "[" );
WriteBaseDisplacement( bdSize, suppressBase, reg );
WriteString( "], " );
WriteIndexRegister( extension );
WriteString( ", " );
WriteOuterDisplacement( TRUE );
END; (* CASE *)
ELSE (* without index *)
CASE Getbits( extension, 2, 0 ) OF
0 : WriteBaseDisplacement( bdSize, suppressBase, reg );
| 1 : Write( "[" );
WriteBaseDisplacement( bdSize, suppressBase, reg );
Write( "]" );
| 2 : Write( "[" );
WriteBaseDisplacement( bdSize, suppressBase, reg );
WriteString( "], " );
WriteOuterDisplacement( FALSE );
| 3 : Write( "[" );
WriteBaseDisplacement( bdSize, suppressBase, reg );
WriteString( "], " );
WriteOuterDisplacement( TRUE );
| 4, 5, 6, 7 : WriteString( "illegal addressing mode." );
END; (* CASE *)
END; (* IF *)
END; (* IF *)
Write( ")" );
END WriteComplexAddrMode;
PROCEDURE SingleAddressDecode( mode, reg, size : INTEGER );
(* Decodes an effective address comletely. Extension words are read if necessary. *)
VAR displacement, address, data : INTEGER;
longAddress, longData : LONGINT;
BEGIN (* SingleAddressDecode *)
CASE mode OF
0 : Write( "D" );
WriteInt( reg );
| 1 : Write( "A" );
WriteInt( reg );
| 2 : WriteString( "(A" );
WriteInt( reg );
Write( ")" );
| 3 : WriteString( "(A" );
WriteInt( reg );
WriteString( ")+" );
| 4 : WriteString( "-(A" );
WriteInt( reg );
Write( ")" );
| 5 : ReadInt( displacement );
Write( "(" );
WriteInt( displacement );
WriteString( ", A" );
WriteInt( reg );
Write( ")" );
| 6 : WriteComplexAddrMode( reg );
| 7 : CASE reg OF
0 : Write( "$" );
ReadInt( address );
WriteHex( address );
| 1 : Write( "$" );
ReadLongint( longAddress );
WriteHex( longAddress );
| 2 : ReadInt( displacement );
Write( "(" );
WriteInt( pc - 2 + displacement );
WriteString( ", CB)" );
| 3 : WriteComplexAddrMode( PC );
| 4 : Write( "#" );
CASE size OF
byte, word :
ReadInt( data );
WriteInt( data );
| long :
ReadLongint( longData );
Write( "$" );
WriteHex( longData );
| other :
WriteString( "illegal operand size." );
END; (* CASE *)
| 5, 6, 7 : WriteString( "illegal addressing mode." );
END; (* CASE *)
END; (* CASE *)
END SingleAddressDecode;
PROCEDURE Format1( op, mode, reg, size : INTEGER );
(* ORI, ANDI, EORI, ADDI, SUBI, CMPI *)
VAR immData : INTEGER;
longImmData : LONGINT;
BEGIN (* Format1 *)
CASE op OF
ORI : WriteString( "ORI" );
| ANDI : WriteString( "ANDI" );
| EORI : WriteString( "EORI" );
| SUBI : WriteString( "SUBI" );
| ADDI : WriteString( "ADDI" );
| CMPI : WriteString( "CMPI" );
ELSE
WriteString( "Illegal instruction." );
END; (* CASE *)
CASE size OF
0 : WriteString( ".B #$" );
ReadInt( immData );
WriteHex( immData );
WriteString( ", " );
IF ( mode = 7 ) & ( reg = 4 ) THEN
WriteString( "CCR" );
ELSE
SingleAddressDecode( mode, reg, byte );
END; (* IF *)
| 1 : WriteString( ".W #$" );
ReadInt( immData );
WriteHex( immData );
WriteString( ", " );
IF ( mode = 7 ) & ( reg = 4 ) THEN
WriteString( "SR" );
ELSE
SingleAddressDecode( mode, reg, word );
END; (* IF *)
| 2 : WriteString( ".L #$" );
ReadLongint( longImmData );
WriteHex( longImmData );
WriteString( ", " );
SingleAddressDecode( mode, reg, long );
| 3 : WriteString( "illegal operand size." );
END; (* CASE *)
END Format1;
PROCEDURE Format2( mode, reg : INTEGER );
(* BFINS *)
VAR instr2 : INTEGER;
BEGIN (* Format2 *)
WriteString( "BFINS " );
ReadInt( instr2 );
Write( "D" );
WriteInt( Getbits( instr2, 14, 12 ) );
WriteString( ", " );
SingleAddressDecode( mode, reg, DUMMY );
WriteString( " {" );
IF Getbits( instr2, 11, 11 ) = 0 THEN
WriteInt( Getbits( instr2, 10, 6 ) );
ELSE
Write( "D" );
WriteInt( Getbits( instr2, 8, 6 ) );
END; (* IF *)
Write( ":" );
IF Getbits( instr2, 5, 5 ) = 0 THEN
WriteInt( Getbits( instr2, 4, 0 ) );
ELSE
Write( "D" );
WriteInt( Getbits( instr2, 2, 0 ) );
END; (* IF *)
Write( "}" );
END Format2;
PROCEDURE Format3( mode, reg, size : INTEGER );
(* CHK2, CMP2 *)
VAR instr2 : INTEGER;
BEGIN (* Format3 *)
ReadInt( instr2 );
IF Getbits( instr2, 10, 0 ) = 0 THEN
IF Getbits( instr2, 11, 11 ) = 0 THEN
WriteString( "CMP2" );
ELSE
WriteString( "CHK2" );
END; (* IF *)
WriteSize( size );
SingleAddressDecode( mode, reg, byte );
WriteString( ", " );
WriteRegister( Getbits( instr2, 15, 15 ), Getbits( instr2, 14, 12 ) );
ELSE
WriteString( "illegal instruction." );
END; (* IF *)
END Format3;
PROCEDURE Format4( op, mode, reg : INTEGER );
(* BCHG, BCLR, BSET, BTST, static bit number. *)
VAR bitNr : INTEGER;
BEGIN (* Format4 *)
CASE op OF
0 : WriteString( "BTST #" );
| 1 : WriteString( "BCHG #" );
| 2 : WriteString( "BCLR #" );
| 3 : WriteString( "BSET #" );
END; (* CASE *)
ReadInt( bitNr );
WriteInt( bitNr );
WriteString( ", " );
SingleAddressDecode( mode, reg, DUMMY );
END Format4;
PROCEDURE Format5( mode, reg, size : INTEGER );
(* CAS, CAS2 *)
VAR instr2, instr3 : INTEGER;
BEGIN (* Format5 *)
ReadInt( instr2 );
IF ( mode = 7 ) & ( reg = 4 ) THEN (* CAS2 *)
ReadInt( instr3 );
WriteString( "CAS2" );
CASE size OF
0, 1 : WriteString( "illegal operand size." );
| 2 : WriteString( ".W D" );
| 3 : WriteString( ".L D" );
END; (* CASE *)
WriteInt( Getbits( instr2, 2, 0 ) );
WriteString( ":D" );
WriteInt( Getbits( instr3, 2, 0 ) );
WriteString( ", D" );
WriteInt( Getbits( instr2, 8, 6 ) );
WriteString( ":D" );
WriteInt( Getbits( instr3, 8, 6 ) );
WriteString( ", (" );
WriteRegister( Getbits( instr2, 15, 15 ), Getbits( instr2, 14, 12 ) );
WriteString( "):(" );
WriteRegister( Getbits( instr3, 15, 15 ), Getbits( instr3, 14, 12 ) );
Write( ")" );
ELSE (* CAS *)
WriteString( "CAS" );
CASE size OF
0 : WriteString( "illegal operand size." );
| 1 : WriteString( ".B D" );
| 2 : WriteString( ".W D" );
| 3 : WriteString( ".L D" );
END; (* CASE *)
WriteInt( Getbits( instr2, 2, 0 ) );
WriteString( ", D" );
WriteInt( Getbits( instr2, 8, 6 ) );
WriteString( ", " );
SingleAddressDecode( mode, reg, DUMMY );
END; (* IF *)
END Format5;
PROCEDURE Format6( mode, reg, size : INTEGER );
(* MOVES *)
VAR instr2 : INTEGER;
BEGIN (* Format6 *)
ReadInt( instr2 );
WriteString( "MOVES" );
WriteSize( size );
IF Getbits( instr2, 11, 11 ) = 0 THEN
SingleAddressDecode( mode, reg, DUMMY );
WriteString( ", " );
WriteRegister( Getbits( instr2, 15, 15 ), Getbits( instr2, 14, 12 ) );
ELSE
WriteRegister( Getbits( instr2, 15, 15 ), Getbits( instr2, 14, 12 ) );
WriteString( ", " );
SingleAddressDecode( mode, reg, DUMMY );
END; (* IF *)
END Format6;
PROCEDURE Format7( da, reg : INTEGER );
(* RTM *)
BEGIN (* Format7 *)
WriteString( "RTM " );
WriteRegister( da, reg );
END Format7;
PROCEDURE Format8( mode, reg : INTEGER );
(* CALLM *)
VAR instr2 : INTEGER;
BEGIN (* Format8 *)
WriteString( "CALLM #" );
ReadInt( instr2 );
WriteInt( instr2 );
WriteString( ", " );
SingleAddressDecode( mode, reg, DUMMY );
END Format8;
PROCEDURE Format9( dataReg, direction, size, addrReg : INTEGER );
(* MOVEP *)
VAR displacement : INTEGER;
BEGIN (* Format9 *)
WriteString( "MOVEP" );
IF size = 0 THEN
WriteString( ".W " );
ELSE
WriteString( ".L " );
END;
ReadInt( displacement );
IF direction = 0 THEN
Write( "(" );
WriteInt( displacement );
WriteString( ", A" );
WriteInt( addrReg );
WriteString( "), D" );
WriteInt( dataReg );
ELSE
Write( "D" );
WriteInt( dataReg );
WriteString( ", (" );
WriteInt( displacement );
WriteString( ", A" );
WriteInt( addrReg );
Write( ")" );
END; (* IF *)
END Format9;
PROCEDURE Format10( op, dataReg, mode, reg : INTEGER );
(* BCHG, BCLR, BSET, BTST, dynamic bit number. *)
BEGIN (* Format10 *)
CASE op OF
0 : WriteString( "BTST D" );
| 1 : WriteString( "BCHG D" );
| 2 : WriteString( "BCLR D" );
| 3 : WriteString( "BSET D" );
END; (* CASE *)
WriteInt( dataReg );
WriteString( ", " );
SingleAddressDecode( mode, reg, DUMMY );
END Format10;
PROCEDURE Format11( size, sourceMode, sourceReg, destMode, destReg : INTEGER );
(* MOVE, MOVEA *)
BEGIN (* Format11 *)
WriteString( "MOVE" );
IF destMode = 1 THEN
Write( "A" );
END; (* IF *)
CASE size OF
0 : WriteString( "illegal operand size." );
| 1 : WriteString( ".B " );
SingleAddressDecode( sourceMode, sourceReg, byte );
| 2 : WriteString( ".L " );
SingleAddressDecode( sourceMode, sourceReg, long );
| 3 : WriteString( ".W " );
SingleAddressDecode( sourceMode, sourceReg, word );
END; (* CASE *)
WriteString( ", " );
SingleAddressDecode( destMode, destReg, DUMMY );
END Format11;
PROCEDURE Format12( op, size, mode, reg : INTEGER );
(* CLR, NEG, NEGX, NOT, TST *)
BEGIN (* Format12 *)
CASE op OF
0 : WriteString( "NEGX" );
| 1 : WriteString( "CLR" );
| 2 : WriteString( "NEG" );
| 3 : WriteString( "NOT" );
| 5 : WriteString( "TST" );
ELSE
WriteString( "illegal instruction." );
END; (* CASE *)
WriteSize( size );
SingleAddressDecode( mode, reg, DUMMY );
END Format12;
PROCEDURE Format13( size, reg : INTEGER );
(* LINK *)
VAR disp : INTEGER;
longDisp : LONGINT;
BEGIN (* Format13 *)
WriteString( "LINK" );
IF size = 0 THEN
WriteString( ".W A" );
WriteInt( reg );
WriteString( ", #" );
ReadInt( disp );
WriteInt( disp );
ELSE
WriteString( ".L A" );
WriteInt( reg );
WriteString( ", #" );
ReadLongint( longDisp );
WriteInt( longDisp );
END; (* IF *)
END Format13;
PROCEDURE Format14( op, mode, reg : INTEGER );
(* JMP, JSR, PEA, NBCD, TAS, ASL, ASR, LSL, LSR, ROL, ROR, ROXL, ROXR *)
BEGIN (* Format14 *)
CASE op OF
JMP : WriteString( "JMP " );
| JSR : WriteString( "JSR " );
| PEA : WriteString( "PEA.L " );
| NBCD : WriteString( "NBCD.B " );
| TAS : WriteString( "TAS.B " );
| ASL : WriteString( "ASL.W " );
| ASR : WriteString( "ASR.W " );
| LSL : WriteString( "LSL.W " );
| LSR : WriteString( "LSR.W " );
| ROL : WriteString( "ROL.W " );
| ROR : WriteString( "ROR.W " );
| ROXL : WriteString( "ROXL.W " );
| ROXR : WriteString( "ROXR.W " );
END; (* CASE *)
SingleAddressDecode( mode, reg, DUMMY );
END Format14;
PROCEDURE Format15( op, data : INTEGER );
(* SWAP, BKPT, TRAP, UNLK, MOVE from USP, RTD, EXT.W, EXT.L, EXTB.L *)
BEGIN (* Format15 *)
CASE op OF
0 : WriteString( "SWAP.W D" );
| 1 : WriteString( "BKPT #" );
| 2 : WriteString( "TRAP #" );
| 3 : WriteString( "UNLK A" );
| 4 : WriteString( "MOVE.L USP, A" );
| 5 : WriteString( "EXT.W D" );
| 6 : WriteString( "EXT.L D" );
| 7 : WriteString( "EXTB.L D" );
END; (* CASE *)
WriteInt( data );
END Format15;
PROCEDURE Format16( reg : INTEGER );
(* MOVE to USP *)
BEGIN (* Format16 *)
WriteString( "MOVE.L A" );
WriteInt( reg );
WriteString( ", USP" );
END Format16;
PROCEDURE Format17( direction : INTEGER );
(* MOVEC *)
VAR instr2 : INTEGER;
BEGIN (* Format17 *)
ReadInt( instr2 );
IF direction = 0 THEN
WriteString( "MOVEC.L Control Register #" );
WriteInt( Getbits( instr2, 11, 0 ) );
WriteString( ", " );
WriteRegister( Getbits( instr2, 15, 15 ), Getbits( instr2, 14, 12 ) );
ELSE
WriteString( "MOVEC.L " );
WriteRegister( Getbits( instr2, 15, 15 ), Getbits( instr2, 14, 12 ) );
WriteString( ", Control Register #" );
WriteInt( Getbits( instr2, 11, 0 ) );
END; (* IF *)
END Format17;
PROCEDURE Format18( op : INTEGER );
(* RTD, STOP *)
VAR data : INTEGER;
BEGIN (* Format18 *)
CASE op OF
RTD : WriteString( "RTD #" );
| STOP : WriteString( "STOP #" );
END; (* CASE *)
ReadInt( data );
WriteInt( data );
END Format18;
PROCEDURE Format19( direction, size, mode, reg : INTEGER );
(* MOVEM *)
VAR regList : INTEGER;
BEGIN (* Format19 *)
IF size = 0 THEN
WriteString( "MOVEM.W " );
ELSE
WriteString( "MOVEM.L " );
END; (* IF *)
ReadInt( regList );
IF direction = 0 THEN
WriteString( "#$" );
WriteHex( regList );
WriteString( ", " );
SingleAddressDecode( mode, reg, DUMMY );
ELSE
SingleAddressDecode( mode, reg, DUMMY );
WriteString( ", #$" );
WriteHex( regList );
END; (* IF *)
END Format19;
PROCEDURE Format20( op, mode, reg : INTEGER );
(* MOVE CCR, MOVE SR *)
BEGIN (* Format20 *)
CASE op OF
0 : (* MOVE from SR *)
WriteString( "MOVE.W SR, " );
SingleAddressDecode( mode, reg, DUMMY );
| 1 : (* MOVE from CCR *)
WriteString( "MOVE.W CCR, " );
SingleAddressDecode( mode, reg, DUMMY );
| 2 : (* MOVE to CCR *)
WriteString( "MOVE.W " );
SingleAddressDecode( mode, reg, word );
WriteString( ", SR" );
| 3 : (* MOVE to SR *)
WriteString( "MOVE.W " );
SingleAddressDecode( mode, reg, word );
WriteString( ", CCR" );
END; (* CASE *)
END Format20;
PROCEDURE Format21( size, dataReg, mode, reg : INTEGER );
(* CHK *)
BEGIN (* Format21 *)
WriteString( "CHK" );
IF size = 1 THEN
WriteString( ".W " );
ELSE
WriteString( ".L " );
END; (* IF *)
SingleAddressDecode( mode, reg, size );
WriteString( ", D" );
WriteInt( dataReg );
END Format21;
PROCEDURE Format22( addrReg, mode, reg : INTEGER );
(* LEA *)
BEGIN (* Format22 *)
WriteString( "LEA " );
SingleAddressDecode( mode, reg, DUMMY );
WriteString( ", A" );
WriteInt( addrReg );
END Format22;
PROCEDURE Format23( condition, reg : INTEGER );
(* DBcc *)
VAR disp : INTEGER;
BEGIN (* Format23 *)
WriteString( "DB" );
WriteCondition( condition );
WriteString( " D" );
WriteInt( reg );
WriteString( ", " );
ReadInt( disp );
WriteInt( pc - 2 + disp );
END Format23;
PROCEDURE Format24( condition, mode, reg : INTEGER );
(* Scc *)
BEGIN (* Format24 *)
Write( "S" );
WriteCondition( condition );
WriteString( ".B " );
SingleAddressDecode( mode, reg, DUMMY );
END Format24;
PROCEDURE Format25( condition, opmode : INTEGER );
(* TRAPcc *)
VAR data : INTEGER;
longData : LONGINT;
BEGIN (* Format25 *)
WriteString( "TRAP" );
WriteCondition( condition );
CASE opmode OF
2 : WriteString( ".W #" );
ReadInt( data );
WriteInt( data );
| 3 : WriteString( ".L #" );
ReadLongint( longData );
WriteInt( longData );
| 4 :
END; (* CASE *)
END Format25;
PROCEDURE Format26( op, data, size, mode, reg : INTEGER );
(* ADDQ, SUBQ *)
BEGIN (* Format26 *)
IF op = 0 THEN
WriteString( "ADDQ" );
ELSE
WriteString( "SUBQ" );
END; (* IF *)
WriteSize( size );
Write( "#" );
IF data = 0 THEN WriteInt( 8 );
ELSE WriteInt( data );
END; (* IF *)
WriteString( ", " );
SingleAddressDecode( mode, reg, DUMMY );
END Format26;
PROCEDURE Format27( condition, displacement : INTEGER );
(* Bcc, BRA, BSR *)
VAR wordDisplacement : INTEGER;
longDisplacement : LONGINT;
BEGIN (* Format27 *)
CASE condition OF
0 : WriteString( "BRA" );
| 1 : WriteString( "BSR" );
ELSE
Write( "B" );
WriteCondition( condition );
END;
CASE displacement OF
0 : WriteString( ".W " );
ReadInt( wordDisplacement );
WriteInt( pc - 2 + wordDisplacement );
| 255 : WriteString( ".L " );
ReadLongint( longDisplacement );
WriteInt( pc - 2 + longDisplacement );
ELSE
WriteString( ".B " );
IF displacement > 127 THEN
WriteInt( pc - 2 + displacement - 256 );
ELSE
WriteInt( pc - 2 + displacement );
END; (* IF *)
END; (* CASE *)
END Format27;
PROCEDURE Format28( reg, data : INTEGER );
(* MOVEQ *)
BEGIN (* Format28 *)
WriteString( "MOVEQ.L #" );
IF data > 127 THEN
WriteInt( data-256 );
ELSE
WriteInt( data );
END; (* IF *)
WriteString( ", D" );
WriteInt( reg );
END Format28;
PROCEDURE Format29( op, mode, reg : INTEGER );
(* MULS, MULU, DIVS, DIVSL, DIVU, DIVUL, long form *)
VAR instr2, size, qReg, rReg : INTEGER;
BEGIN (* Format29 *)
ReadInt( instr2 );
size := Getbits( instr2, 10, 10 );
qReg := Getbits( instr2, 14, 12 );
rReg := Getbits( instr2, 2, 0 );
IF op = MUL THEN
WriteString( "MUL" );
ELSE
WriteString( "DIV" );
END; (* IF *)
IF Getbits( instr2, 11, 11 ) = 0 THEN
Write( "U" );
ELSE
Write( "S" );
END; (* IF *)
IF ( op = dIV ) & ( size = 0 ) & ( rReg # qReg ) THEN
Write( "L" );
END; (* IF *)
WriteString( ".L " );
SingleAddressDecode( mode, reg, long );
WriteString( ", " );
IF qReg # rReg THEN
Write( "D" );
WriteInt( rReg );
Write( ":" );
END; (* IF *)
Write( "D" );
WriteInt( qReg );
END Format29;
PROCEDURE Format30( op, signed, dataReg, mode, reg : INTEGER );
(* MULS, MULU, DIVS, DIVU, short form *)
BEGIN (* Format30 *)
IF op = MUL THEN
IF signed = 0 THEN
WriteString( "MULU.W " );
ELSE
WriteString( "MULS.W " );
END;
ELSE
IF signed = 0 THEN
WriteString( "DIVU.W " );
ELSE
WriteString( "DIVS.W " );
END;
END;
SingleAddressDecode( mode, reg, word );
WriteString( ", D" );
WriteInt( dataReg );
END Format30;
PROCEDURE Format31( op, direction, dataReg, size, mode, reg : INTEGER );
(* ADD, AND, CMP, EOR, OR, SUB *)
BEGIN (* Format31 *)
CASE op OF
ADD : WriteString( "ADD" );
| AND : WriteString( "AND" );
| CMP : WriteString( "CMP" );
| EOR : WriteString( "EOR" );
| oR : WriteString( "OR" );
| SUB : WriteString( "SUB" );
END; (* CASE *)
WriteSize( size );
IF direction = 0 THEN
SingleAddressDecode( mode, reg, size );
WriteString( ", D" );
WriteInt( dataReg );
ELSE
Write( "D" );
WriteInt( dataReg );
WriteString( ", " );
SingleAddressDecode( mode, reg, size );
END; (* IF *)
END Format31;
PROCEDURE Format32( op, size, rm, xReg, yReg : INTEGER );
(* ABCD, SBCD, ADDX, SUBX *)
BEGIN (* Format32 *)
CASE op OF
ABCD : WriteString( "ABCD" );
| SBCD : WriteString( "SBCD" );
| ADDX : WriteString( "ADDX" );
| SUBX : WriteString( "SUBX" );
END; (* CASE *)
WriteSize( size );
IF rm = 0 THEN
Write( "D" );
WriteInt( xReg );
WriteString( ", D" );
WriteInt( yReg );
ELSE
WriteString( "-(A" );
WriteInt( xReg );
WriteString( "), -(A" );
WriteInt( yReg );
Write( ")" );
END; (* IF *)
END Format32;
PROCEDURE Format33( op, rm, xReg, yReg : INTEGER );
(* PACK, UNPK *)
VAR adjustment : INTEGER;
BEGIN (* Format33 *)
IF op = PACK THEN
WriteString( "PACK " );
ELSE
WriteString( "UNPK " );
END; (* IF *)
IF rm = 0 THEN
Write( "D" );
WriteInt( xReg );
WriteString( ", D" );
WriteInt( yReg );
ELSE
WriteString( "-(A" );
WriteInt( xReg );
WriteString( "), -(A" );
WriteInt( yReg );
Write( ")" );
END; (* IF *)
WriteString( ", #" );
ReadInt( adjustment );
WriteInt( adjustment );
END Format33;
PROCEDURE Format34( op, size, addrReg, mode, reg : INTEGER );
(* ADDA, CMPA, SUBA *)
BEGIN (* Format34 *)
CASE op OF
ADDA : WriteString( "ADDA" );
| CMPA : WriteString( "CMPA" );
| SUBA : WriteString( "SUBA" );
END; (* CASE *)
IF size = 0 THEN
WriteString( ".W " );
ELSE
WriteString( ".L " );
END; (* IF *)
SingleAddressDecode( mode, reg, size+1 );
WriteString( ", A" );
WriteInt( addrReg );
END Format34;
PROCEDURE Format35( size, xReg, yReg : INTEGER );
(* CMPM *)
BEGIN (* Format35 *)
WriteString( "CMPM" );
WriteSize( size );
WriteString( "(A" );
WriteInt( yReg );
WriteString( ")+, (A" );
WriteInt( xReg );
WriteString( ")+" );
END Format35;
PROCEDURE Format36( opmode, xReg, yReg : INTEGER );
(* EXG *)
BEGIN (* Format36 *)
WriteString( "EXG.L " );
CASE opmode OF
16 : Write( "D" );
WriteInt( xReg );
WriteString( ", D" );
WriteInt( yReg );
| 17 : Write( "A" );
WriteInt( xReg );
WriteString( ", A" );
WriteInt( yReg );
| 33 : Write( "D" );
WriteInt( xReg );
WriteString( ", A" );
WriteInt( yReg );
ELSE
WriteString( "illegal instruction." );
END; (* CASE *)
END Format36;
PROCEDURE Format37( op, mode, reg : INTEGER );
(* BFCHG, BFCLR, BFSET, BTST *)
VAR instr2 : INTEGER;
BEGIN (* Format37 *)
CASE op OF
BFCHG : WriteString( "BFCHG " );
| BFCLR : WriteString( "BFCLR " );
| BFSET : WriteString( "BFSET " );
| BFTST : WriteString( "BFTST " );
END; (* CASE *)
ReadInt( instr2 );
SingleAddressDecode( mode, reg, DUMMY );
WriteString( " {" );
IF Getbits( instr2, 11, 11 ) = 0 THEN
WriteInt( Getbits( instr2, 10, 6 ) );
ELSE
Write( "D" );
WriteInt( Getbits( instr2, 8, 6 ) );
END; (* IF *)
Write( ":" );
IF Getbits( instr2, 5, 5 ) = 0 THEN
WriteInt( Getbits( instr2, 4, 0 ) );
ELSE
Write( "D" );
WriteInt( Getbits( instr2, 2, 0 ) );
END; (* IF *)
Write( "}" );
END Format37;
PROCEDURE Format38( op, mode, reg : INTEGER );
(* BFEXTS, BFEXTU, BFFFO *)
VAR instr2 : INTEGER;
BEGIN (* Format38 *)
CASE op OF
BFEXTS : WriteString( "BFEXTS " );
| BFEXTU : WriteString( "BFEXTU " );
| BFFFO : WriteString( "BFFFO " );
END; (* CASE *)
ReadInt( instr2 );
SingleAddressDecode( mode, reg, DUMMY );
WriteString( " {" );
IF Getbits( instr2, 11, 11 ) = 0 THEN
WriteInt( Getbits( instr2, 10, 6 ) );
ELSE
Write( "D" );
WriteInt( Getbits( instr2, 8, 6 ) );
END; (* IF *)
Write( ":" );
IF Getbits( instr2, 5, 5 ) = 0 THEN
WriteInt( Getbits( instr2, 4, 0 ) );
ELSE
Write( "D" );
WriteInt( Getbits( instr2, 2, 0 ) );
END; (* IF *)
WriteString( "}, D" );
WriteInt( Getbits( instr2, 14, 12 ) );
END Format38;
PROCEDURE Format39( op, cntReg, direction, size, ir, reg : INTEGER );
(* ASL, ASR, LSL, ROXL, ROXR, ROL, ROR *)
BEGIN (* Format39 *)
CASE op OF
0 : WriteString( "AS" );
| 1 : WriteString( "LS" );
| 2 : WriteString( "ROX" );
| 3 : WriteString( "RO" );
END; (* CASE *)
IF direction = 0 THEN
Write( "R" );
ELSE
Write( "L" );
END; (* IF *)
WriteSize( size );
IF ir = 0 THEN
Write( "#" );
IF cntReg = 0 THEN
Write( "8" );
ELSE
WriteInt( cntReg );
END; (* IF *)
ELSE
Write( "D" );
WriteInt( cntReg );
END; (* IF *)
WriteString( ", D" );
WriteInt( reg );
END Format39;
PROCEDURE Format40( destReg, romoffs : INTEGER );
(* FMOVECR *)
BEGIN (* Format40 *)
WriteString( "FMOVECR.X $" );
WriteHex( romoffs );
WriteString( ", FP" );
WriteInt( destReg );
END Format40;
PROCEDURE Format41( opcode, mode, reg, rm, sourceSpec, destReg : INTEGER );
(* normal coprocessor operation *)
VAR size : INTEGER;
BEGIN (* Format41 *)
CASE opcode OF
FABS : WriteString( "FABS." );
| FACOS : WriteString( "FACOS." );
| FADD : WriteString( "FADD." );
| FASIN : WriteString( "FASIN." );
| FATAN : WriteString( "FATAN." );
| FATANH : WriteString( "FATANH." );
| FCMP : WriteString( "FCMP." );
| FCOS : WriteString( "FCOS." );
| FCOSH : WriteString( "FCOSH." );
| FDIV : WriteString( "FDIV." );
| FETOX : WriteString( "FETOX." );
| FETOXM1 : WriteString( "FETOXM1." );
| FGETEXP : WriteString( "FGETEXP." );
| FGETMAN : WriteString( "FGETMAN." );
| FINT : WriteString( "FINT." );
| FINTRZ : WriteString( "FINTRZ." );
| FLOG10 : WriteString( "FLOG10." );
| FLOG2 : WriteString( "FLOG2." );
| FLOGN : WriteString( "FLOGN." );
| FLOGNP1 : WriteString( "FLOGNP1." );
| FMOD : WriteString( "FMOD." );
| FMOVE : WriteString( "FMOVE." );
| FMUL : WriteString( "FMUL." );
| FNEG : WriteString( "FNEG." );
| FREM : WriteString( "FREM." );
| FSCALE : WriteString( "FSCALE." );
| FSGLDIV : WriteString( "FSGLDIV." );
| FSGLMUL : WriteString( "FSGLMUL." );
| FSIN : WriteString( "FSIN." );
| FSINH : WriteString( "FSINH." );
| FSQRT : WriteString( "FSQRT." );
| FSUB : WriteString( "FSUB." );
| FTAN : WriteString( "FTAN." );
| FTANH : WriteString( "FTANH." );
| FTENTOX : WriteString( "FTENTOX." );
| FTST : WriteString( "FTST." );
| FTWOTOX : WriteString( "FTWOTOX." );
ELSE
WriteString( "illegal coprocessor instruction." );
END; (* CASE *)
IF rm = 0 THEN
WriteString( "X FP" );
WriteInt( sourceSpec );
ELSE
WriteFloatFormat( sourceSpec, size );
SingleAddressDecode( mode, reg, size );
END; (* IF *)
WriteString( ", FP" );
WriteInt( destReg );
END Format41;
PROCEDURE Format42( mode, reg, rm, sourceSpec, destRegSin, destRegCos : INTEGER );
(* FSINCOS *)
VAR size : INTEGER;
BEGIN (* Format42 *)
WriteString( "FSINCOS." );
IF rm = 0 THEN
WriteString( "X FP" );
WriteInt( sourceSpec );
ELSE
WriteFloatFormat( sourceSpec, size );
SingleAddressDecode( mode, reg, size );
END; (* IF *)
WriteString( ", FP" );
WriteInt( destRegCos );
WriteString( ":FP" );
WriteInt( destRegSin );
END Format42;
PROCEDURE Format43( mode, reg, dr, regList : INTEGER );
(* FMOVE(M) FPcr *)
PROCEDURE WriteControlRegs( fpcr, fpsr, fpiar : INTEGER );
(* Writes a list of floating point control registers. *)
VAR comma : BOOLEAN;
BEGIN (* WriteControlRegs *)
comma := FALSE;
IF fpcr = 1 THEN
WriteString( "FPCR" );
comma := TRUE;
END;
IF fpsr = 1 THEN
IF comma THEN WriteString( ", " ); END;
WriteString( "FPSR" );
comma := TRUE;
END;
IF fpiar = 1 THEN
IF comma THEN WriteString( ", " ); END;
WriteString( "FPIAR" );
END;
END WriteControlRegs;
BEGIN (* Format43 *)
WriteString( "FMOVEM.L " );
IF dr = 0 THEN
SingleAddressDecode( mode, reg, long );
WriteString( ", " );
WriteControlRegs( Getbits( regList, 2, 2 ), Getbits( regList, 1, 1 ), Getbits( regList, 0, 0 ) );
ELSE
WriteControlRegs( Getbits( regList, 2, 2 ), Getbits( regList, 1, 1 ), Getbits( regList, 0, 0 ) );
WriteString( ", " );
SingleAddressDecode( mode, reg, long );
END; (* IF *)
END Format43;
PROCEDURE Format44( mode, reg, dr, statdyn, regList : INTEGER );
(* FMOVEM FPn *)
BEGIN (* Format44 *)
WriteString( "FMOVEM.X " );
IF dr = 0 THEN
SingleAddressDecode( mode, reg, byte );
IF statdyn = 0 THEN (* static *)
WriteString( ", #" );
WriteHex( regList );
ELSE (* dynamic *)
WriteString( ", D" );
WriteInt( Getbits( regList, 6, 4 ) );
END; (* IF *)
ELSE
IF statdyn = 0 THEN (* static *)
Write( "#" );
WriteHex( regList );
ELSE (* dynamic *)
Write( "D" );
WriteInt( Getbits( regList, 6, 4 ) );
END; (* IF *)
WriteString( ", " );
SingleAddressDecode( mode, reg, DUMMY );
END; (* IF *)
END Format44;
PROCEDURE Format45( mode, reg, sourceReg, destFormat, kfactor : INTEGER );
(* FMOVE from FPn *)
VAR size : INTEGER;
BEGIN (* Format45 *)
WriteString( "FMOVE." );
WriteFloatFormat( destFormat, size );
WriteString( "FP" );
WriteInt( sourceReg );
WriteString( ", " );
SingleAddressDecode( mode, reg, size );
IF destFormat = 3 THEN (* static k-factor *)
WriteString( "{#" );
WriteInt( kfactor );
Write( "}" );
ELSIF destFormat = 7 THEN (* dynamic k-factor *)
WriteString( "{D" );
WriteInt( Getbits( kfactor, 6, 4 ) );
Write( "}" );
END;
END Format45;
PROCEDURE Format46( reg, condition : INTEGER );
(* FDBcc *)
VAR disp : INTEGER;
BEGIN (* Format46 *)
WriteString( "FDB" );
WriteFloatCondition( condition );
WriteString( " D" );
WriteInt( reg );
WriteString( ", " );
ReadInt( disp );
WriteInt( pc - 2 + disp );
END Format46;
PROCEDURE Format47( mode, reg, condition : INTEGER );
(* FScc *)
BEGIN (* Format47 *)
WriteString( "FS" );
WriteFloatCondition( condition );
WriteString( ".B " );
SingleAddressDecode( mode, reg, byte );
END Format47;
PROCEDURE Format48( mode, condition : INTEGER );
(* FTRAPcc *)
VAR data : INTEGER;
longdata : LONGINT;
BEGIN (* Format48 *)
WriteString( "FTRAP" );
WriteFloatCondition( condition );
CASE mode OF
2 :
ReadInt( data );
WriteString( ".W #" );
WriteInt( data );
| 3 :
ReadLongint( longdata );
WriteString( ".L #" );
WriteInt( longdata );
| 4 : (* nothing *)
ELSE
WriteString( "illegal operand mode." );
END; (* CASE *)
END Format48;
PROCEDURE Format49( size, condition : INTEGER );
(* FBcc *)
VAR disp : INTEGER;
longdisp : LONGINT;
BEGIN (* Format49 *)
WriteString( "FB" );
WriteFloatCondition( condition );
IF size = 0 THEN
WriteString( ".W " );
ReadInt( disp );
WriteInt( pc - 2 + disp );
ELSE
WriteString( ".L " );
ReadLongint( longdisp );
WriteInt( pc - 2 + longdisp );
END; (* IF *)
END Format49;
PROCEDURE Format50( opcode, mode, reg : INTEGER );
(* FSAVE, FRESTORE *)
BEGIN (* Format50 *)
CASE opcode OF
4 : WriteString( "FSAVE " );
| 5 : WriteString( "FRESTORE " );
ELSE
WriteString( "illegal coprocessor instruction." );
END; (* CASE *)
SingleAddressDecode( mode, reg, long );
END Format50;
PROCEDURE Format51( nr : INTEGER );
(* TRAP *)
BEGIN (* Format51 *)
WriteString( "TRAP #" );
WriteInt( nr );
END Format51;
PROCEDURE CoprocessorDecode( instruction, mode, reg : INTEGER );
(* Decodes a coprocessor instruction. *)
VAR cpinstruction : INTEGER;
BEGIN (* CoprocessorDecode *)
IF Getbits( instruction, 11, 9 ) # 1 THEN
WriteString( "wrong coprocessor." );
ELSE
CASE Getbits( instruction, 8, 6 ) OF
0 :
ReadInt( cpinstruction );
IF ( Getbits( cpinstruction, 15, 15 ) = 0 ) & ( Getbits( cpinstruction, 13, 13 ) = 0 ) THEN
IF Getbits( cpinstruction, 12, 10 ) = 7 THEN (* FMOVECR *)
IF Getbits( instruction, 5, 0 ) = 0 THEN (* FMOVECR *)
Format40( Getbits( cpinstruction, 9, 7 ), Getbits( cpinstruction, 6, 0 ) );
ELSE
WriteString( "illegal coprocessor instruction." );
END; (* IF *)
ELSE (* normal coprocessor operation *)
IF Getbits( cpinstruction, 6, 3 ) = 6 THEN (* FSINCOS *)
Format42( mode, reg, Getbits( cpinstruction, 14, 14 ), Getbits( cpinstruction, 12, 10 ),
Getbits( cpinstruction, 9, 7 ), Getbits( cpinstruction, 2, 0 ) );
ELSE (* normal coprocessor operation *)
Format41( Getbits( cpinstruction, 6, 0 ), mode, reg, Getbits( cpinstruction, 14, 14 ),
Getbits( cpinstruction, 12, 10 ), Getbits( cpinstruction, 9, 7 ) );
END; (* IF *)
END; (* IF *)
ELSE (* FMOVE from FPn, FMOVE FPcr, FMOVEM FPn, FMOVEM FPcr *)
IF Getbits( cpinstruction, 15, 14 ) = 2 THEN (* FMOVE(M) FPcr *)
Format43( mode, reg, Getbits( cpinstruction, 13, 13 ), Getbits( cpinstruction, 12, 10 ) );
ELSIF Getbits( cpinstruction, 15, 14 ) = 3 THEN (* FMOVEM FPn *)
Format44( mode, reg, Getbits( cpinstruction, 13, 13 ), Getbits( cpinstruction, 11, 11 ),
Getbits( cpinstruction, 7, 0 ) );
ELSIF Getbits( cpinstruction, 15, 13 ) = 3 THEN (* FMOVE from FPn *)
Format45( mode, reg, Getbits( cpinstruction, 9, 7 ), Getbits( cpinstruction, 12, 10 ),
Getbits( cpinstruction, 6, 0 ) );
ELSE
WriteString( "illegal coprocessor instruction." );
END; (* IF *)
END; (* IF *)
| 1 : (* FDBcc, FScc, FTRAPcc *)
ReadInt( cpinstruction );
CASE mode OF
1 : (* FDBcc *)
Format46( reg, Getbits( cpinstruction, 5, 0 ) );
| 7 : (* FTRAPcc, FScc *)
IF reg <= 1 THEN (* FScc *)
Format47( mode, reg, Getbits( cpinstruction, 5, 0 ) );
ELSE (* FTRAPcc *)
Format48( reg, Getbits( cpinstruction, 5, 0 ) );
END; (* IF *)
ELSE (* FScc *)
Format47( mode, reg, Getbits( cpinstruction, 5, 0 ) );
END; (* CASE *)
| 2 : (* FBcc, FNOP *)
IF Getbits( instruction, 5, 0 ) = 0 THEN (* FNOP *)
ReadInt( cpinstruction );
WriteString( "FNOP" );
ELSE (* FBcc *)
Format49( 0, Getbits( instruction, 5, 0 ) );
END; (* IF *)
| 3 : (* FBcc *)
Format49( 1, Getbits( instruction, 5, 0 ) );
| 4, 5 : (* FSAVE, FRESTORE *)
Format50( Getbits( instruction, 8, 6 ), mode, reg );
| 6, 7 :
WriteString( "illegal coprocessor instruction." );
END; (* CASE *)
END; (* IF *)
END CoprocessorDecode;
PROCEDURE DecodeIns( instruction : INTEGER );
(* Decodes the given instruction and reads extension words if necessary. *)
VAR size, mode, reg, op2 : INTEGER;
BEGIN (* DecodeIns *)
op2 := Getbits( instruction, 11, 9 );
size := Getbits( instruction, 7, 6 );
mode := Getbits( instruction, 5, 3 );
reg := Getbits( instruction, 2, 0 );
CASE Getbits( instruction, 15, 12 ) OF
0 : (* ADDI, ANDI, BCHG, BCLR, BSET, BTST, CALLM, CAS, CAS2, CHK2, CMPI, CMP2, EORI, MOVEP, MOVES,
ORI, RTM, SUBI *)
IF Getbits( instruction, 8, 8) = 0 THEN (* ADDI, ANDI, BCHG, BCLR, BSET, BTST, CALLM, CAS, CAS2, CHK2,
CMPI, CMP2, EORI, MOVES, ORI, RTM, SUBI *)
CASE op2 OF
0 : (* CHK2.B, CMP2.B, ORI *)
IF size = 3 THEN (* CHK2.B, CMP2.B *)
Format3( mode, reg, 0 );
ELSE (* ORI *)
Format1( ORI, mode, reg, size );
END; (* IF *)
| 1 : (* ANDI, CHK2.W, CMP2.W *)
IF size = 3 THEN (* CHK2.W, CMP2.W *)
Format3( mode, reg, 1 );
ELSE (* ANDI *)
Format1( ANDI, mode, reg, size );
END; (* IF *)
| 2 : (* CHK2.L, CMP2.L, SUBI *)
IF size = other THEN (* CHK2.L, CMP2.L *)
Format3( mode, reg, 2 );
ELSE (* SUBI *)
Format1( SUBI, mode, reg, size );
END; (* IF *)
| 3 : (* ADDI, CALLM, RTM *)
IF size = other THEN (* CALLM, RTM *)
IF Getbits( instruction, 5, 4 ) = 0 THEN (* RTM *)
Format7( Getbits( instruction, 3, 3 ), reg );
ELSE (* CALLM *)
Format8( mode, reg );
END; (* IF *)
ELSE (* ADDI *)
Format1( ADDI, mode, reg, size );
END; (* IF *)
| 4 : (* BCHG, BCLR, BSET, BTST *)
Format4( Getbits( instruction, 8, 6 ), mode, reg );
| 5 : (* CAS.B, EORI *)
IF size = other THEN (* CAS.B *)
Format5( mode, reg, 1 );
ELSE (* EORI *)
Format1( EORI, mode, reg, size );
END; (* IF *)
| 6 : (* CAS.W, CAS2.W, CMPI *)
IF size = other THEN (* CAS.W, CAS2.W *)
Format5( mode, reg, 2 );
ELSE (* CMPI *)
Format1( CMPI, mode, reg, size );
END; (* IF *)
| 7 : (* CAS.L, CAS2.L, MOVES *)
IF size = other THEN (* CAS.L, CAS2.L *)
Format5( mode, reg, 3 );
ELSE (* CMPI *)
Format6( mode, reg, size );
END; (* IF *)
END; (* CASE *)
ELSE (* Bit 8 = 1: BCHG, BCLR, BSET, BTST, MOVEP *)
IF mode = 1 THEN (* MOVEP *)
Format9( op2, Getbits( instruction, 7, 7 ), Getbits( instruction, 6, 6 ), reg );
ELSE (* BCHG, BCLR, BSET, BTST *)
Format10( size, op2, mode, reg );
END; (* IF *)
END; (* IF *)
| 1, 2, 3 : (* MOVE, MOVEA *)
Format11( Getbits( instruction, 13, 12 ), mode, reg, Getbits( instruction, 8, 6 ), op2 );
| 4 : (* BKPT, CHK, CLR, DIVS, DIVSL, DIVU, DIVUL, EXT, EXTB, ILLEGAL, JMP, JSR, LEA, LINK, special MOVE,
MOVEC, MOVEM, MULS, MULU, NBCD, NEG, NEGX, NOP, NOT, PEA, RESET, RTD, RTE, RTR, RTS, STOP,
SWAP, TAS, TRAP, TRAPV, TST, UNLK *)
CASE Getbits( instruction, 8, 6 ) OF
0 : (* CLR.B, LINK.L, MULS, MULU, NBCD, NEG.B, NEGX.B, NOT.B, TST.B *)
CASE op2 OF
0, 1, 2, 3, 5 : (* NEGX.B, CLR.B, NEG.B, NOT.B, TST.B *)
Format12( op2, 0, mode, reg );
| 4 : (* LINK.L, NBCD *)
IF Getbits( instruction, 5, 3 ) = 1 THEN (* LINK.L *)
Format13( 1, Getbits( instruction, 2, 0 ) );
ELSE (* NBCD *)
Format14( NBCD, mode, reg );
END; (* IF *)
| 6 : (* MULS, MULU *)
Format29( MUL, mode, reg );
| 7 : WriteString( "illegal instruction." );
END; (* CASE *)
| 1 : (* BKPT, CLR.W, DIVS, DIVSL, DIVU, DIVUL, LINK.W, MOVE USP, MOVEC, NEG.W, NEGX.W, NOP,
NOT.W, PEA, RESET, RTD, RTE, RTR, RTS, STOP, SWAP, TRAP, TRAPV, TST.W, UNLK *)
CASE op2 OF
0, 1, 2, 3, 5 : (* NEGX.W, CLR.W, NEG.W, NOT.W, TST.W *)
Format12( op2, 1, mode, reg );
| 4 : (* BKPT, PEA, SWAP *)
IF Getbits( instruction, 5, 3 ) <= 1 THEN (* SWAP, BKPT *)
Format15( mode, reg );
ELSE (* PEA *)
Format14( PEA, mode, reg );
END; (* IF *)
| 6 : (* DIVS, DIVSL, DIVU, DIVUL *)
Format29( dIV, mode, reg );
| 7 : (* LINK.W, MOVE USP, MOVEC, NOP, RESET, RTD, RTE, RTR, RTS, STOP, TRAP, TRAPV, UNLK *)
CASE Getbits( instruction, 5, 3 ) OF
0, 1 : (* TRAP *)
Format51( Getbits( instruction, 3, 0 ) );
| 2 : (* LINK.W *)
Format13( 0, reg );
| 3 : (* UNLK *)
Format15( 3, reg );
| 4 : (* MOVE to USP *)
Format16( reg );
| 5 : (* MOVE from USP *)
Format15( 4, reg );
| 6 : (* NOP, RESET, RTD, RTE, RTR, RTS, STOP, TRAPV *)
CASE reg OF
0 : WriteString( "RESET" );
| 1 : WriteString( "NOP" );
| 2 : Format18( STOP );
| 3 : WriteString( "RTE" );
| 4 : Format18( RTD );
| 5 : WriteString( "RTS" );
| 6 : WriteString( "TRAPV" );
| 7 : WriteString( "RTR" );
END; (* CASE *)
| 7 : (* MOVEC *)
Format17( Getbits( instruction, 0, 0 ) );
END; (* CASE *)
END; (* CASE *)
| 2 : (* CLR.L, EXT.W, JSR, MOVEM.W, NEG.L, NEGX.L, NOT.L, TST.L *)
CASE op2 OF
0, 1, 2, 3, 5 : (* NEGX.L, CLR.L, NEG.L, NOT.L, TST.L *)
Format12( op2, size, mode, reg );
| 4 : (* EXT.W, MOVEM.W *)
IF mode = 0 THEN (* EXT.W *)
Format15( 5, reg );
ELSE (* MOVEM.W *)
Format19( 0, 0, mode, reg );
END; (* IF *)
| 6 : (* MOVEM.W *)
Format19( 1, 0, mode, reg );
| 7 : (* JSR *)
Format14( JSR, mode, reg );
END; (* CASE *)
| 3 : (* EXT.L, ILLEGAL, JMP, MOVE CCR, MOVE SR, MOVEM.L, TAS *)
CASE op2 OF
0, 1, 2, 3 : (* MOVE CCR, MOVE SR *)
Format20( op2, mode, reg );
| 4 : (* EXT.L, MOVEM.L *)
IF mode = 0 THEN (* EXT.L *)
Format15( 6, reg );
ELSE (* MOVEM.L *)
Format19( 0, 1, mode, reg );
END; (* IF *)
| 5 : (* ILLEGAL, TAS *)
IF Getbits( instruction, 5, 0 ) = 60 THEN (* ILLEGAL *)
WriteString( "ILLEGAL" );
ELSE (* TAS *)
Format14( TAS, mode, reg );
END; (* IF *)
| 6 : (* MOVEM.L *)
Format19( 1, 1, mode, reg );
| 7 : (* JMP *)
Format14( JMP, mode, reg );
END; (* CASE *)
| 4 : (* CHK.L *)
Format21( 2, op2, mode, reg );
| 5 : WriteString( "illegal instruction." );
| 6 : (* CHK.W *)
Format21( 1, op2, mode, reg );
| 7 : (* EXTB.L, LEA *)
IF mode = 0 THEN (* EXTB.L *)
Format15( 7, reg );
ELSE (* LEA *)
Format22( op2, mode, reg );
END; (* IF *)
END; (* CASE *)
| 5 : (* ADDQ, DBcc, Scc, SUBQ, TRAPcc *)
IF size = other THEN (* DBcc, Scc, TRAPcc *)
CASE mode OF
1 : (* DBcc *)
Format23( Getbits( instruction, 11, 8 ), reg );
| 7 : (* Scc, TRAPcc *)
IF reg <= 1 THEN (* Scc *)
Format24( Getbits( instruction, 11, 8 ), mode, reg );
ELSE (* TRAPcc *)
Format25( Getbits( instruction, 11, 8 ), reg );
END; (* IF *)
ELSE (* Scc *)
Format24( Getbits( instruction, 11, 8 ), mode, reg );
END; (* CASE *)
ELSE (* ADDQ, SUBQ *)
Format26( Getbits( instruction, 8, 8 ), op2, size, mode, reg );
END; (* IF *)
| 6 : (* Bcc, BRA, BSR *)
Format27( Getbits( instruction, 11, 8 ), Getbits( instruction, 7, 0 ) );
| 7 : (* MOVEQ *)
Format28( op2, Getbits( instruction, 7, 0 ) );
| 8 : (* DIVS, DIVU, OR, PACK, SBCD, UNPK *)
CASE Getbits( instruction, 8, 6 ) OF
0, 1, 2 : (* OR *)
Format31( oR, 0, op2, size, mode, reg );
| 3 : (* DIVU *)
Format30( dIV, 0, op2, mode, reg );
| 4 : (* OR, SBCD *)
IF Getbits( instruction, 5, 4 ) = 0 THEN (* SBCD *)
Format32( SBCD, 0, Getbits( instruction, 3, 3 ), reg, op2 );
ELSE (* OR *)
Format31( oR, 1, op2, 0, mode, reg );
END; (* IF *)
| 5 : (* OR, PACK *)
IF Getbits( instruction, 5, 4 ) = 0 THEN (* PACK *)
Format33( PACK, Getbits( instruction, 3, 3 ), reg, op2 );
ELSE (* OR *)
Format31( oR, 1, op2, 1, mode, reg );
END; (* IF *)
| 6 : (* OR, UNPK *)
IF Getbits( instruction, 5, 4 ) = 0 THEN (* UNPK *)
Format33( UNPK, Getbits( instruction, 3, 3 ), reg, op2 );
ELSE (* OR *)
Format31( oR, 1, op2, 2, mode, reg );
END; (* IF *)
| 7 : (* DIVS *)
Format30( dIV, 1, op2, mode, reg );
END; (* CASE *)
| 9 : (* SUB, SUBA, SUBX *)
IF size = 3 THEN (* SUBA *)
Format34( SUBA, Getbits( instruction, 8, 8 ), op2, mode, reg );
ELSE (* SUB, SUBX *)
IF ( Getbits( instruction, 8, 8 ) = 1 ) & ( Getbits( instruction, 5, 4 ) = 0 ) THEN (* SUBX *)
Format32( SUBX, size, Getbits( instruction, 3, 3 ), reg, op2 );
ELSE (* SUB *)
Format31( SUB, Getbits( instruction, 8, 8 ), op2, size, mode, reg );
END; (* IF *)
END; (* IF *)
| 10 : WriteString( "illegal instruction." );
| 11 : (* CMP, CMPA, CMPM, EOR *)
CASE Getbits( instruction, 8, 6 ) OF
0, 1, 2 : (* CMP *)
Format31( CMP, 0, op2, size, mode, reg );
| 3, 7 : (* CMPA *)
Format34( CMPA, Getbits( instruction, 8, 8 ), op2, mode, reg );
| 4, 5, 6 : (* CMPM, EOR *)
IF Getbits( instruction, 5, 3 ) = 1 THEN (* CMPM *)
Format35( size, op2, reg );
ELSE (* EOR *)
Format31( EOR, 1, op2, size, mode, reg );
END; (* IF *)
END; (* CASE *)
| 12 : (* ABCD, AND, EXG, MULS, MULU *)
CASE Getbits( instruction, 8, 6 ) OF
0, 1, 2 : (* AND *)
Format31( AND, 0, op2, size, mode, reg );
| 3 : (* MULU *)
Format30( MUL, 0, op2, mode, reg );
| 4 : (* ABCD, AND.B *)
IF Getbits( instruction, 5, 4 ) = 0 THEN (* ABCD *)
Format32( ABCD, 0, Getbits( instruction, 3, 3 ), reg, op2 );
ELSE (* AND.B *)
Format31( AND, 1, op2, 0, mode, reg );
END; (* IF *)
| 5 : (* AND.W, EXG *)
IF Getbits( instruction, 5, 4 ) = 0 THEN (* EXG *)
Format36( Getbits( instruction, 7, 3 ), op2, reg );
ELSE (* AND.W *)
Format31( AND, 1, op2, 1, mode, reg );
END; (* IF *)
| 6 : (* AND.L, EXG *)
IF Getbits( instruction, 5, 4 ) = 0 THEN (* EXG *)
Format36( Getbits( instruction, 7, 3 ), op2, reg );
ELSE (* AND.L *)
Format31( AND, 1, op2, 2, mode, reg );
END; (* IF *)
| 7 : (* MULS *)
Format30( MUL, 1, op2, mode, reg );
END; (* CASE *)
| 13 : (* ADD, ADDA, ADDX *)
IF size = other THEN (* ADDA *)
Format34( ADDA, Getbits( instruction, 8, 8 ), op2, mode, reg );
ELSE (* ADD, ADDX *)
IF ( Getbits( instruction, 8, 8 ) = 1 ) & ( Getbits( instruction, 5, 4 ) = 0 ) THEN (* ADDX *)
Format32( ADDX, size, Getbits( instruction, 3, 3 ), reg, op2 );
ELSE (* ADD *)
Format31( ADD, Getbits( instruction, 8, 8 ), op2, size, mode, reg );
END; (* IF *)
END; (* IF *)
| 14 : (* ASL, ASR, BFCHG, BFCLR, BFEXTS, BFEXTU, BFFFO, BFINS, BFSET, BFTST, LSL, LSR, ROL, ROR, ROXL,
ROXR *)
IF size = other THEN (* bit field operations, memory shifts and rotates *)
CASE Getbits( instruction, 11, 8 ) OF
0 : (* ASR *) Format14( ASR, mode, reg );
| 1 : (* ASL *) Format14( ASL, mode, reg );
| 2 : (* LSR *) Format14( LSR, mode, reg );
| 3 : (* LSL *) Format14( LSL, mode, reg );
| 4 : (* ROXR *) Format14( ROXR, mode, reg );
| 5 : (* ROXL *) Format14( ROXL, mode, reg );
| 6 : (* ROR *) Format14( ROR, mode, reg );
| 7 : (* ROL *) Format14( ROL, mode, reg );
| 8 : (* BFTST *) Format37( BFTST, mode, reg );
| 9 : (* BFEXTU *) Format38( BFEXTU, mode, reg );
| 10 : (* BFCHG *) Format37( BFCHG, mode, reg );
| 11 : (* BFEXTS *) Format38( BFEXTS, mode, reg );
| 12 : (* BFCLR *) Format37( BFCLR, mode, reg );
| 13 : (* BFFFO *) Format38( BFFFO, mode, reg);
| 14 : (* BFSET *) Format37( BFSET, mode, reg );
| 15 : (* BFINS *) Format2( mode, reg );
END; (* CASE *)
ELSE (* register shifts and rotates *)
Format39( Getbits( instruction, 4, 3 ), op2, Getbits( instruction, 8, 8 ), size,
Getbits( instruction, 5, 5 ), reg );
END; (* IF *)
| 15 : (* coprocessor *)
CoprocessorDecode( instruction, mode, reg );
END; (* CASE *)
END DecodeIns;
PROCEDURE ReadHeader( VAR entries, commands, pointers, imports : INTEGER;
VAR constSize, codeSize, refLen : LONGINT; VAR error : BOOLEAN );
(* Reads the header block and writes the information to the output. *)
VAR ch : CHAR;
link : INTEGER;
modName : ARRAY 24 OF CHAR;
key, dsize, refPos : LONGINT;
BEGIN (* ReadHeader *)
Read( ch );
IF ch # 0F1X THEN
WriteString( "No object file." );
error := TRUE;
ELSE
Read( ch );
ReadLongint( refPos );
ReadLongint( refLen );
ReadInt( entries );
ReadInt( commands );
ReadInt( pointers );
ReadInt( imports );
ReadInt( link );
ReadLongint( dsize );
ReadLongint( constSize );
ReadLongint( codeSize );
ReadLongint( key );
ReadString( modName, 24 );
WriteString( "Module: " );
WriteString( modName );
WriteLn;
WriteString( "Key: " );
WriteInt( key );
WriteLn; WriteLn;
WriteString( "Link: " );
WriteInt( link );
WriteLn; WriteLn;
WriteString( "Data size: " );
WriteInt( dsize );
WriteLn; WriteLn;
Texts.Append( output, writer.buf );
END; (* IF *)
END ReadHeader;
PROCEDURE ReadEntries( entries : INTEGER; VAR error : BOOLEAN );
(* Reads the enties from the file and writes them to the output. *)
VAR i : INTEGER;
ch : CHAR;
entry : LONGINT;
BEGIN (* ReadEntries *)
IF ~ error THEN
WriteString( "Entries: " );
Read( ch );
IF ch # 82X THEN
WriteString( BlockMisaligned );
WriteLn;
error := TRUE;
ELSE
WriteInt( entries );
WriteLn;
FOR i := 0 TO entries - 1 DO
ReadLongint( entry );
WriteInt( entry );
WriteLn;
END; (* FOR *)
WriteLn;
END; (* IF *)
END; (* IF *)
Texts.Append( output, writer.buf );
END ReadEntries;
PROCEDURE ReadCommands( commands : INTEGER; VAR error : BOOLEAN );
(* Reads the commands from the file and writes them to the output. *)
VAR i : INTEGER;
ch : CHAR;
name : ARRAY 100 OF CHAR;
entry : LONGINT;
BEGIN (* ReadCommands *)
IF ~ error THEN
WriteString( "Commands: " );
Read( ch );
IF ch # 83X THEN
WriteString( BlockMisaligned );
WriteLn;
error := TRUE;
ELSE
WriteInt( commands );
WriteLn;
FOR i := 0 TO commands - 1 DO
ReadString( name, 0 );
WriteString( name );
WriteString( ": " );
ReadLongint( entry );
WriteInt( entry );
WriteLn;
END; (* FOR *)
WriteLn;
END; (* IF *)
END; (* IF *)
Texts.Append( output, writer.buf );
END ReadCommands;
PROCEDURE ReadPointers( pointers : INTEGER; VAR error : BOOLEAN );
(* Reads the global pointers from the file and writes them to the output. *)
VAR i : INTEGER;
ch : CHAR;
adr : LONGINT;
BEGIN (* ReadPointers *)
IF ~ error THEN
WriteString( "Pointers: " );
Read( ch );
IF ch # 84X THEN
WriteString( BlockMisaligned );
WriteLn;
error := TRUE;
ELSE
WriteInt( pointers );
WriteLn;
FOR i := 0 TO pointers - 1 DO
ReadLongint( adr );
WriteInt( adr );
WriteLn;
END; (* FOR *)
WriteLn;
END; (* IF *)
END; (* IF *)
Texts.Append( output, writer.buf );
END ReadPointers;
PROCEDURE ReadImports( imports : INTEGER; VAR error : BOOLEAN );
(* Reads the imports from the file and writes them to the output. *)
VAR i : INTEGER;
ch : CHAR;
name : ARRAY 30 OF CHAR;
adr : LONGINT;
BEGIN (* ReadImports *)
IF ~ error THEN
WriteString( "Imports: " );
Read( ch );
IF ch # 85X THEN
WriteString( BlockMisaligned );
WriteLn;
error := TRUE;
ELSE
WriteInt( imports );
WriteLn;
FOR i := 0 TO imports - 1 DO
ReadLongint( adr );
ReadString( name, 0 );
WriteString( name );
WriteString( ": " );
WriteInt( adr );
WriteLn;
END; (* FOR *)
WriteLn;
END; (* IF *)
END; (* IF *)
Texts.Append( output, writer.buf );
END ReadImports;
PROCEDURE ReadConst( size : LONGINT; VAR error : BOOLEAN );
(* Reads the constants from the file and writes them in decimal format to the output. *)
VAR i : LONGINT;
ch : CHAR;
BEGIN (* ReadConst *)
IF ~ error THEN
WriteString( "Constants: " );
Read( ch );
IF ch # 86X THEN
WriteString( BlockMisaligned );
WriteLn;
error := TRUE;
ELSE
WriteInt( size );
WriteLn;
FOR i := 0 TO size - 1 DO
Read( ch );
WriteInt( ORD( ch ) );
Write( " " );
IF i MOD 20 = 19 THEN WriteLn; END;
END; (* FOR *)
WriteLn;
WriteLn;
END; (* IF *)
END; (* IF *)
Texts.Append( output, writer.buf );
END ReadConst;
PROCEDURE ReadCode( size : LONGINT; VAR error : BOOLEAN );
(* Reads the code from the file and decodes it to the output. *)
VAR ch : CHAR;
instruction : INTEGER;
BEGIN (* ReadCode *)
IF ~ error THEN
WriteString( "Code: " );
Read( ch );
IF ch # 87X THEN
WriteString( BlockMisaligned );
WriteLn;
error := TRUE;
ELSE
WriteInt( size );
WriteLn;
pc := 0;
REPEAT
WriteInt( pc );
WriteString( " " );
ReadInt( instruction );
DecodeIns( instruction );
WriteLn;
Texts.Append( output, writer.buf );
UNTIL pc >= size;
WriteLn;
END; (* IF *)
END; (* IF *)
Texts.Append( output, writer.buf );
END ReadCode;
PROCEDURE ReadRef( VAR error : BOOLEAN );
(* Reads the reference information from the file. *)
VAR adr : LONGINT;
ch : CHAR;
name : ARRAY 256 OF CHAR;
BEGIN (* ReadRef *)
IF ~ error THEN
WriteString( "References: " );
Read( ch );
IF ch # 88X THEN
WriteString( BlockMisaligned );
WriteLn;
error := TRUE;
ELSE
WriteLn;
Read( ch );
ReadDynint( adr );
WHILE ~rider.eof DO
WriteString( "Procedure: " );
ReadString( name, 0 );
WriteString( name );
WriteString( " " );
WriteInt( adr );
WriteLn;
Read( ch );
WHILE ( ~rider.eof ) & ( ch # 0F8X ) DO
IF ch = 1X THEN WriteString( " Variable: " );
ELSE WriteString( " Var-Parameter: " );
END;
Read( ch );
ReadDynint( adr );
ReadString( name, 0 );
WriteString( name );
WriteType( ch );
WriteInt( adr );
WriteLn;
Read( ch );
END; (* WHILE *)
ReadDynint( adr );
END; (* WHILE *)
END; (* IF *)
END; (* IF *)
Texts.Append( output, writer.buf );
END ReadRef;
PROCEDURE Decode*;
(* Translates the code in the file after the call into a viewer. *)
VAR vx, vy : INTEGER;
entries, commands, pointers, imports : INTEGER;
constSize, codeSize, refLen : LONGINT;
error : BOOLEAN;
beg, end, time: LONGINT;
text : Texts.Text;
BEGIN (* Disassemble *)
Texts.OpenScanner( scanner, Oberon.Par.text, Oberon.Par.pos );
Texts.Scan( scanner );
IF ( scanner.class = Texts.Char ) & ( scanner.c = "^" ) OR ( scanner.line # 0 ) THEN
Oberon.GetSelection( text, beg, end, time );
IF time >= 0 THEN Texts.OpenScanner( scanner, text, beg ); Texts.Scan( scanner ) END
END;
IF scanner.class = Texts.Name THEN
file := Files.Old( scanner.s );
IF file = NIL THEN
Texts.OpenWriter( writer );
Texts.WriteString( writer, "File not found: '" );
Texts.WriteString( writer, scanner.s );
Texts.Write( writer, "'" );
Texts.WriteLn( writer );
Texts.Append( Oberon.Log, writer.buf );
ELSE
Files.Set( rider, file, 0 );
NEW( output );
Texts.Open( output, "" );
output.notify := TextFrames.NotifyDisplay;
frame := TextFrames.NewText( output, 0 );
Oberon.AllocateUserViewer( Oberon.Par.vwr.X, vx, vy );
NEW( viewer );
viewer := MenuViewers.New( TextFrames.NewMenu( "AsmCode",
"System.Close System.Copy System.Grow Edit.Search Edit.Store" ), frame, TextFrames.menuH, vx, vy );
Texts.OpenWriter( writer );
error := FALSE;
ReadHeader( entries, commands, pointers, imports, constSize, codeSize, refLen, error );
ReadEntries( entries, error );
ReadCommands( commands, error );
ReadPointers( pointers, error );
ReadImports( imports, error );
ReadConst( constSize, error );
ReadCode( codeSize, error );
ReadRef( error );
END; (* IF *)
END; (* IF *)
END Decode;
END Decoder.